package com.imooc.security;

import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Test;


/**
 * 对称加密算法：AES，是目前使用最多的对称加密算法
 * 与3DES相比，速度更快
 * 官方公布尚未被破解
 * 常用于一点通信系统加密以及基于SSH协议的软件
 * @author Administrator
 *
 */
public class ImoocAes {
	//private static String srcStr= "imooc security aes";
	
	public static void main(String[] args) {
		//1.定义一个字符串；
		String srcStr = "003000000026";
		//1-2.定义一个密钥;
		//String aesKey = jdkAESKey();
		String aesKey = jdkAESKey("wwwwwwwwwwwwwwwww");
		//2.传入字符串,得到加密字符串；
		String enStr = jdkAESEncrpt(srcStr, aesKey);
		//3.传入加密字符串，得到字符串；
		String deStr = jdkAESDecrpt(enStr,aesKey);
		
//		JDK AES encrypt加密:TYD6y2tQWcGyx+pY1a+uPjzBjs76ANbmDKP/g0w1Lxo=
//				JDK AES DECRYPT解密: imooc security aes
	}

	/**
	 * JDK AES密钥：设定长度为128的密钥；
	 * 
	 */
	public static String jdkAESKey(){
		
		try {
			//生成KEY
			KeyGenerator keyGenerator =KeyGenerator.getInstance("AES");
			keyGenerator.init(128);//要生成多少位，只需要修改这里即可128, 192或256
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] keyBytes = secretKey.getEncoded();
			System.out.println(Arrays.toString(keyBytes));
			String keyStr =  Base64.getEncoder().encodeToString(keyBytes);
			System.out.println("加密的密钥："+ keyStr);
			
			return keyStr;
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
		
	}
	/**
	 * JDK AES密钥:指定字符串生成密钥；
	 * 
	 */
	public static String jdkAESKey(String srcKeyStr){
		
		try {
			//生成KEY
			KeyGenerator keyGenerator =KeyGenerator.getInstance("AES");
			keyGenerator.init(128,new SecureRandom(srcKeyStr.getBytes()));//要生成多少位，只需要修改这里即可128, 192或256
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] keyBytes = secretKey.getEncoded();
			System.out.println(Arrays.toString(keyBytes));
			String keyStr =  Base64.getEncoder().encodeToString(keyBytes);
			System.out.println("加密的密钥："+ keyStr);
			
			return keyStr;
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
		
	}
	
	
	
	/**
	 * JDK AES加密
	 * 
	 */
	public static String jdkAESEncrpt(String srcStr,String keyStr){
		
		try {
			byte[] keyBytes = Base64.getDecoder().decode(keyStr);
			System.out.println("加密的密钥："+Arrays.toString(keyBytes));
			
			//Key转化
			Key convertSecretKey = new SecretKeySpec(keyBytes,"AES");
			
			//加密；
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
			byte[] result = cipher.doFinal(srcStr.getBytes());
			String resultStr = Base64.getEncoder().encodeToString(result);
			System.out.println("JDK AES encrypt加密:"+resultStr);
			return resultStr;
						
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
		
	}
	
	/**
	 * JDK AES解密
	 * 
	 */
	public static String jdkAESDecrpt(String srcStr,String keyStr){
		
		try {
			byte[] keyBytes = Base64.getDecoder().decode(keyStr);
			System.out.println("加密的密钥："+Arrays.toString(keyBytes));			
			//Key转化
			Key convertSecretKey = new SecretKeySpec(keyBytes,"AES");
			
			//解密
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
			byte[] result = cipher.doFinal(Base64.getDecoder().decode(srcStr));
			String resultStr = new String(result);
			System.out.println("JDK AES DECRYPT解密: "+resultStr);
			return resultStr;
						
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
		
	}	
	/**
	 * JDK AES加密解密
	 * 
	 */
	@Test
	public void jdkAES(){
		String srcStr= "imooc security aes";		
		try {
			//生成KEY
			KeyGenerator keyGenerator =KeyGenerator.getInstance("AES");
			keyGenerator.init(128);
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] keyBytes = secretKey.getEncoded();
			System.out.println("加密的密钥："+Hex.encodeHexString(keyBytes));
			
			//Key转化
			Key convertSecretKey = new SecretKeySpec(keyBytes,"AES");
			
			//加密；
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
			byte[] result = cipher.doFinal(srcStr.getBytes());
			String resultStr = Hex.encodeHexString(result);
			System.out.println("JDK AES encrypt加密:"+resultStr);
			
			//解密
			cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
			result = cipher.doFinal(result);
			resultStr = new String(result);
			System.out.println("JDK AES DECRYPT解密: "+resultStr);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	/**
	 * BC,AES
	 */
	@Test
	public void bcAes(){
		String srcStr= "imooc security aes";		
		try {
			Security.addProvider(new BouncyCastleProvider());
			//生成Key;
			//生成KEY
			KeyGenerator keyGenerator =KeyGenerator.getInstance("AES","BC");
			System.out.println(keyGenerator.getProvider());
			keyGenerator.init(128);
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] keyBytes = secretKey.getEncoded();
			//Key转化
			Key convertSecretKey = new SecretKeySpec(keyBytes,"AES");
			
			//加密；
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
			byte[] result = cipher.doFinal(srcStr.getBytes());
			String resultStr = Hex.encodeHexString(result);
			System.out.println("BC AES encrypt加密:"+resultStr);
			
			//解密
			cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
			result = cipher.doFinal(result);
			resultStr = new String(result);
			System.out.println("BC AES DECRYPT解密: "+resultStr);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
